﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/*
 *  PicSizeInMapUnits=pic_size_in_map_units_minus1 + 1
 *  SliceGroupChangeRate=slice_group_change_rate_minus1 + 1
 *  
 *  slice_type ref slice list
 *  0    P
 *  1    B
 *  2    I
 *  3    SP
 *  4    SI
 *  5    P
 *  6    B
 *  7    I
 *  8    SP
 *  9    SI
 *  
 *  when slice_type between 5 and 9, exclude current slice_type,all other silce in cuurent picture should equal current slice_type or equal current slice_typ - 5
 *  when nal_unit_type==5(IDR pic)  slice type should equal in (2,4,7,9)
 *  when num_ref_frames==0 slice type equal in (2,4,7,9)
 */

namespace FormatTest
{
    /// <summary>
    /// 条带头语法
    /// </summary>
    public class slice_header : base_func
    {
        public int slice_type;

        public int num_ref_idx_l0_active_minus1;

        public int num_ref_idx_l1_active_minus1;

        public int first_mb_in_slice;

        public int field_pic_flag;

        public int slice_group_change_cycle;

        public slice_header(string bytes)
        {
            base.bytes = bytes;
            first_mb_in_slice = columbus_ue();
            slice_type = columbus_ue();
            var pic_parameter_set_id = columbus_ue();
            var frame_num = columbus_ue();
            field_pic_flag = 0;
            if (DecodeH264.vseq_parameter_set_rbsp.frame_mbs_only_flag == 0)
            {
                field_pic_flag = Convert.ToInt32(read_bits(1));
                if (field_pic_flag != 0)
                {
                    var bottom_field_flag = read_bits(1);
                }
            }
            if (DecodeH264.vnal_unit.nal_unit_type == 5)
            {
                var idr_pic_id = columbus_ue();
            }
            if (DecodeH264.vseq_parameter_set_rbsp.pic_order_cnt_type == 0)
            {
                var pic_order_cnt_lsb = columbus_ue();
                if (DecodeH264.vpic_parameter_set_rbsp.pic_order_present_flag != 0 && field_pic_flag == 0)
                {
                    var delta_pic_order_cnt_bottom = columbus_se();
                }
            }
            var delta_pic_order_cnt = new int[2];
            if (DecodeH264.vseq_parameter_set_rbsp.pic_order_cnt_type == 1 && DecodeH264.vseq_parameter_set_rbsp.delta_pic_order_always_zero_flag == 0)
            {
                delta_pic_order_cnt[0] = columbus_se();
                if (DecodeH264.vpic_parameter_set_rbsp.pic_order_present_flag != 0 && field_pic_flag == 0)
                {
                    delta_pic_order_cnt[1] = columbus_se();
                }
            }
            if (DecodeH264.vpic_parameter_set_rbsp.redundant_pic_cnt_present_flag != 0)
            {
                var redundant_pic_cnt = columbus_ue();
            }

            if (slice_type == 1 || slice_type == 6)
            {
                var direct_spatial_mv_pred_flag = read_one_bit();
            }
            if (slice_type == 0 || slice_type == 5 || slice_type == 1 || slice_type == 6 || slice_type == 3 || slice_type == 8)
            {
                var num_ref_idx_active_override_flag = read_one_bit();
                if (num_ref_idx_active_override_flag != 0)
                {
                    num_ref_idx_l0_active_minus1 = columbus_ue();
                    if (slice_type == 1 || slice_type == 6)
                    {
                        num_ref_idx_l1_active_minus1 = columbus_ue();
                    }
                }
            }
            ref_pic_list_reordering();
            if (DecodeH264.vpic_parameter_set_rbsp.weighted_pred_flag != 0 && (slice_type == 5 || slice_type == 0 || slice_type == 3 || slice_type == 8) || (DecodeH264.vpic_parameter_set_rbsp.weighted_bipred_idc == 1 && (slice_type == 1 || slice_type == 6)))
            {
                pred_weight_table();
            }
            if (DecodeH264.vnal_unit.nal_ref_idc != 0)
            {
                dec_ref_pic_marking();
            }
            var slice_qp_delta = columbus_se();
            if (slice_type == 3 || slice_type == 8 || slice_type == 5 || slice_type == 9)
            {
                if (slice_type == 3 || slice_type == 8)
                {
                    var sp_for_switch_flag = read_one_bit();
                    var slice_qs_delta = columbus_se();
                }
            }
            if (DecodeH264.vpic_parameter_set_rbsp.deblocking_filter_control_present_flag != 0)
            {
                var disable_deblocking_filter_idc = columbus_ue();
                if (disable_deblocking_filter_idc != 1)
                {
                    var slice_alpha_c0_offset_div2 = columbus_se();
                    var slice_beta_offset_div2 = columbus_se();
                }
            }
            if (DecodeH264.vpic_parameter_set_rbsp.num_slice_groups_minus1 > 0 && DecodeH264.vpic_parameter_set_rbsp.slice_group_map_type >= 3 && DecodeH264.vpic_parameter_set_rbsp.slice_group_map_type <= 5)
            {
                var PicSizeInMapUnits = DecodeH264.vpic_parameter_set_rbsp.pic_size_in_map_units_minus1 + 1;
                var SliceGroupChangeRate = DecodeH264.vpic_parameter_set_rbsp.slice_group_change_rate_minus1 + 1;
                slice_group_change_cycle = TwoToTen(read_bits(Convert.ToInt32(Math.Ceiling(Math.Log(PicSizeInMapUnits / SliceGroupChangeRate + 1)))));

            }
        }

        /// <summary>
        /// 参考图像列表重排序语法
        /// </summary>
        private void ref_pic_list_reordering()
        {
            if ((slice_type != 2 || slice_type != 7) && (slice_type != 4 || slice_type != 9))
            {
                var ref_pic_list_reordering_flag_l0 = read_one_bit();
                if (ref_pic_list_reordering_flag_l0 != 0)
                {
                    var reordering_of_pic_nums_idc = columbus_ue();
                    do
                    {
                        reordering_of_pic_nums_idc = columbus_ue();
                        if (reordering_of_pic_nums_idc == 0 ||
reordering_of_pic_nums_idc == 1)
                        {
                            var abs_diff_pic_num_minus1 = columbus_ue();
                        }
                        else if (reordering_of_pic_nums_idc == 2)
                        {
                            var long_term_pic_num = columbus_ue();
                        }
                    }
                    while (reordering_of_pic_nums_idc != 3);
                }
            }
            if (slice_type == 1 || slice_type == 6)
            {
                var ref_pic_list_reordering_flag_l1 = read_one_bit();
                if (ref_pic_list_reordering_flag_l1 != 0)
                {
                    var reordering_of_pic_nums_idc = 0;
                    do
                    {
                        reordering_of_pic_nums_idc = columbus_ue();
                        if (reordering_of_pic_nums_idc == 0 ||
reordering_of_pic_nums_idc == 1)
                        {
                            var abs_diff_pic_num_minus1 = columbus_ue();
                        }
                        else if (reordering_of_pic_nums_idc == 2)
                        {
                            var long_term_pic_num = columbus_ue();
                        }
                    }
                    while (reordering_of_pic_nums_idc != 3);
                }
            }
        }

        /// <summary>
        /// 预测加权表格语法
        /// </summary>
        private void pred_weight_table()
        {
            var luma_log2_weight_denom = columbus_ue();
            if (DecodeH264.vseq_parameter_set_rbsp.chroma_format_idc != 0)
            {
                var chroma_log2_weight_denom = columbus_ue();
            }
            var luma_weight_l0 = new int[num_ref_idx_l0_active_minus1];
            var luma_offset_l0 = new int[num_ref_idx_l0_active_minus1];
            var chroma_weight_l0 = new int[num_ref_idx_l0_active_minus1, 2];
            var chroma_offset_l0 = new int[num_ref_idx_l0_active_minus1, 2];
            for (var i = 0; i <= num_ref_idx_l0_active_minus1; i++)
            {
                var luma_weight_l0_flag = read_one_bit();
                if (luma_weight_l0_flag != 0)
                {
                    luma_weight_l0[i] = columbus_se();
                    luma_offset_l0[i] = columbus_se();
                }
                if (DecodeH264.vseq_parameter_set_rbsp.chroma_format_idc != 0)
                {
                    var chroma_weight_l0_flag = read_one_bit();
                    if (chroma_weight_l0_flag != 0)
                    {
                        for (var j = 0; j < 2; j++)
                        {
                            chroma_weight_l0[i, j] = columbus_se();
                            chroma_offset_l0[i, j] = columbus_se();
                        }
                    }
                }
            }
            if (slice_type == 1 || slice_type == 6)
            {
                var luma_weight_l1 = new int[num_ref_idx_l1_active_minus1];
                var luma_offset_l1 = new int[num_ref_idx_l1_active_minus1];
                var chroma_weight_l1 = new int[num_ref_idx_l1_active_minus1, 2];
                var chroma_offset_l1 = new int[num_ref_idx_l1_active_minus1, 2];
                for (var i = 0; i <= num_ref_idx_l1_active_minus1; i++)
                {
                    var luma_weight_l1_flag = read_one_bit();
                    if (luma_weight_l1_flag != 0)
                    {
                        luma_weight_l1[i] = columbus_se();
                        luma_offset_l1[i] = columbus_se();
                    }
                    if (DecodeH264.vseq_parameter_set_rbsp.chroma_format_idc != 0)
                    {
                        var chroma_weight_l1_flag = read_one_bit();
                        if (chroma_weight_l1_flag != 0)
                        {
                            for (var j = 0; j < 2; j++)
                            {
                                chroma_weight_l1[i, j] = columbus_se();
                                chroma_offset_l1[i, j] = columbus_se();
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 解码的参考图像标识语法
        /// </summary>
        private void dec_ref_pic_marking()
        {
            if (DecodeH264.vnal_unit.nal_unit_type == 5)
            {
                var no_output_of_prior_pics_flag = read_one_bit();
                var long_term_reference_flag = read_one_bit();
            }
            else
            {
                var adaptive_ref_pic_marking_mode_flag = read_one_bit();
                if (adaptive_ref_pic_marking_mode_flag != 0)
                {
                    var memory_management_control_operation = 0;
                    do
                    {
                        memory_management_control_operation = columbus_ue();
                        if (memory_management_control_operation == 1 || memory_management_control_operation == 3)
                        {
                            var difference_of_pic_nums_minus1 = columbus_ue();
                        }
                        if (memory_management_control_operation == 2)
                        {
                            var long_term_pic_num = columbus_ue();
                        }
                        if (memory_management_control_operation == 3 || memory_management_control_operation == 6)
                        {
                            var long_term_frame_idx = columbus_ue();
                        }
                        if (memory_management_control_operation == 4)
                        {
                            var max_long_term_frame_idx_plus1 = columbus_ue();
                        }
                    }
                    while (memory_management_control_operation != 0);
                }
            }
        }
    }
}
